package chat.client;

import chat.utils.Constants;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataOutputStream;
import java.net.Socket;

public class ClientChat implements ActionListener {
    // 登录界面
    private JFrame loginView;
    private JTextField ipEt, nameEt;
    private Socket socket;


    // --------------------------------


    // 聊天界面
    private JFrame win = new JFrame();
    // 消息内容框架
    public JTextArea smsContent = new JTextArea(23, 50);
    // 发送消息的框
    private JTextArea smsSend = new JTextArea(4, 40);
    // 展示在线人数的窗口
    public JList<String> onLineUsers = new JList<>();
    // 是否私聊按钮
    private JCheckBox isPrivateBn = new JCheckBox("私聊");
    // 消息按钮
    private JButton sendBn = new JButton("发送");


    public static void main(String[] args) {
        new ClientChat().initView();
    }

    private void initView() {
        // 初始化聊天窗口
        win.setSize(650, 600);

        //展示登录界面
        displayLoginView();
    }

    private void displayLoginView() {
        loginView = new JFrame("登录");
        loginView.setLayout(new GridLayout(3, 1));
        loginView.setSize(500, 230);

        JPanel ip = new JPanel();
        JLabel label = new JLabel("   IP:");
        ip.add(label);
        ipEt = new JTextField(20);
        ip.add(ipEt);
        loginView.add(ip);

        JPanel name = new JPanel();
        JLabel label1 = new JLabel("Name:");
        name.add(label1);
        nameEt = new JTextField(20);
        name.add(nameEt);
        loginView.add(name);

        JPanel btnView = new JPanel();
        JButton login = new JButton("登陆");
        btnView.add(login);
        JButton cancle = new JButton("取消");
        btnView.add(cancle);
        loginView.add(btnView);
        // 关闭窗口退出当前程序
        loginView.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setWindowCenter(loginView, 500, 260, true);

        /** 给登录和取消绑定点击事件 */
        login.addActionListener(this);
        cancle.addActionListener(this);
    }

    private static void setWindowCenter(JFrame frame, int width, int height, boolean flag) {
        /** 得到所在系统所在屏幕的宽高 */
        Dimension ds = frame.getToolkit().getScreenSize();

        /** 拿到电脑的宽 */
        int width1 = ds.width;
        /** 高 */
        int height1 = ds.height;

        /** 设置窗口的左上角坐标 */
        frame.setLocation(width1 / 2 - width / 2, height1 / 2 - height / 2);
        frame.setVisible(flag);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        // 获取点击源
        JButton btn = (JButton) e.getSource();
        switch (btn.getText()) {
            case "登陆":
                String ip = ipEt.getText().toString();
                String name = nameEt.getText().toString();
                // 校验参数是否为空
                // 错误提示
                String msg = "";
                // 12.1.2.0
                // \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\
                if (ip == null || !ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) {
                    msg = "请输入合法的服务端ip地址";
                } else if (name == null || !name.matches("\\S{1,}")) {
                    msg = "姓名必须1个字符以上";
                }

                if (!msg.equals("")) {
                    /** msg有内容说明参数有为空 */
                    // 参数一：弹出放到哪个窗口里面
                    JOptionPane.showMessageDialog(loginView, msg);
                } else {
                    try {
                        // 参数都合法了
                        // 当前登录的用户,去服务端登陆
                        /** 先把当前用户的名称展示到界面 */
                        win.setTitle(name);
                        // 去服务端登陆连接一个socket管道
                        socket = new Socket(ip, Constants.PORT);

                        //为客户端的socket分配一个线程 专门负责收消息
                        new ClientReader(this, socket).start();

                        // 带上用户信息过去
                        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                        dos.writeInt(1); // 登录消息
                        dos.writeUTF(name.trim());
                        dos.flush();

                        // 关系当前窗口 弹出聊天界面
                        loginView.dispose(); // 登录窗口销毁
                        displayChatView(); // 展示了聊天窗口了


                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
                break;
            case "取消":
                /** 退出系统 */
                System.exit(0);
                break;
            case "发送":
                // 得到发送消息的内容
                String msgSend = smsSend.getText().toString();
                if (!msgSend.trim().equals("")) {
                    /** 发消息给服务端 */
                    try {
                        // 判断是否对谁发消息
                        String selectName = onLineUsers.getSelectedValue();
                        int flag = 2;// 群发 @消息
                        if (selectName != null && !selectName.equals("")) {
                            msgSend = ("@" + selectName + "," + msgSend);
                            /** 判断是否选中了私法 */
                            if (isPrivateBn.isSelected()) {
                                /** 私法 */
                                flag = 3;//私发消息
                            }

                        }

                        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                        dos.writeInt(flag); // 群发消息  发送给所有人
                        dos.writeUTF(msgSend);
                        if (flag == 3) {
                            // 告诉服务端我对谁私发
                            dos.writeUTF(selectName.trim());
                        }
                        dos.flush();

                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }

                }
                smsSend.setText(null);
                break;
        }
    }

    private void displayChatView() {
        JPanel bottomPanel = new JPanel(new BorderLayout());
        //-----------------------------------------------
        // 将消息框和按钮 添加到窗口的底端
        win.add(bottomPanel, BorderLayout.SOUTH);
        bottomPanel.add(smsSend);
        JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT));
        btns.add(sendBn);
        btns.add(isPrivateBn);
        bottomPanel.add(btns, BorderLayout.EAST);
        //-----------------------------------------------
        // 给发送消息按钮绑定点击事件监听器
        // 将展示消息区centerPanel添加到窗口的中间
        smsContent.setBackground(new Color(0xdd, 0xdd, 0xdd));
        // 让展示消息区可以滚动。
        win.add(new JScrollPane(smsContent), BorderLayout.CENTER);
        smsContent.setEditable(false);
        //-----------------------------------------------
        // 用户列表和是否私聊放到窗口的最右边
        Box rightBox = new Box(BoxLayout.Y_AXIS);
        onLineUsers.setFixedCellWidth(120);
        onLineUsers.setVisibleRowCount(13);
        rightBox.add(new JScrollPane(onLineUsers));
        win.add(rightBox, BorderLayout.EAST);
        //-----------------------------------------------
        // 关闭窗口退出当前程序
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        win.pack();  // swing 加上这句 就可以拥有关闭窗口的功能
        /** 设置窗口居中,显示出来  */
        setWindowCenter(win, 650, 600, true);
        // 发送按钮绑定点击事件
        sendBn.addActionListener(this);
    }
}
